#!/bin/bash

# 部署状态检查脚本
# 用于验证个人云笔记系统的部署状态

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# 配置
DEPLOY_PATH="${1:-/opt/personal-cloud-notes}"
APP_PORT="3000"
DB_NAME="personal_cloud_notes"
DB_USER="notes_user"
DEPLOY_USER="notes"

print_message() {
    local color="$1"
    local message="$2"
    echo -e "${color}${message}${NC}"
}

print_title() {
    local title="$1"
    echo
    print_message "$CYAN" "=================================="
    print_message "$CYAN" "$title"
    print_message "$CYAN" "=================================="
}

print_check() {
    local status="$1"
    local message="$2"
    if [[ "$status" == "pass" ]]; then
        print_message "$GREEN" "✓ $message"
    elif [[ "$status" == "fail" ]]; then
        print_message "$RED" "✗ $message"
    else
        print_message "$YELLOW" "⚠ $message"
    fi
}

# 检查系统服务
check_services() {
    print_title "系统服务状态"
    
    local services_ok=true
    
    # 检查Nginx
    if systemctl is-active nginx >/dev/null 2>&1; then
        print_check "pass" "Nginx服务运行正常"
    else
        print_check "fail" "Nginx服务未运行"
        services_ok=false
    fi
    
    # 检查MySQL
    if systemctl is-active mysql >/dev/null 2>&1 || systemctl is-active mysqld >/dev/null 2>&1; then
        print_check "pass" "MySQL服务运行正常"
    else
        print_check "fail" "MySQL服务未运行"
        services_ok=false
    fi
    
    return $services_ok
}

# 检查端口监听
check_ports() {
    print_title "端口监听状态"
    
    local ports_ok=true
    
    # 检查HTTP端口
    if netstat -tlnp 2>/dev/null | grep -q ":80 " || ss -tlnp 2>/dev/null | grep -q ":80 "; then
        print_check "pass" "HTTP端口 80 监听正常"
    else
        print_check "fail" "HTTP端口 80 未监听"
        ports_ok=false
    fi
    
    # 检查应用端口
    if netstat -tlnp 2>/dev/null | grep -q ":$APP_PORT " || ss -tlnp 2>/dev/null | grep -q ":$APP_PORT "; then
        print_check "pass" "应用端口 $APP_PORT 监听正常"
    else
        print_check "fail" "应用端口 $APP_PORT 未监听"
        ports_ok=false
    fi
    
    return $ports_ok
}

# 检查应用状态
check_application() {
    print_title "应用状态"
    
    local app_ok=true
    
    # 检查PM2进程
    if sudo -u "$DEPLOY_USER" pm2 list 2>/dev/null | grep -q "personal-cloud-notes.*online"; then
        print_check "pass" "PM2应用进程运行正常"
    else
        print_check "fail" "PM2应用进程未运行"
        app_ok=false
    fi
    
    # 检查应用文件
    if [[ -f "$DEPLOY_PATH/server/app.js" ]]; then
        print_check "pass" "应用主文件存在"
    else
        print_check "fail" "应用主文件不存在"
        app_ok=false
    fi
    
    # 检查配置文件
    if [[ -f "$DEPLOY_PATH/.env" ]]; then
        print_check "pass" "环境配置文件存在"
    else
        print_check "fail" "环境配置文件不存在"
        app_ok=false
    fi
    
    # 检查PM2配置
    if [[ -f "$DEPLOY_PATH/ecosystem.config.js" ]]; then
        print_check "pass" "PM2配置文件存在"
    else
        print_check "fail" "PM2配置文件不存在"
        app_ok=false
    fi
    
    return $app_ok
}

# 检查数据库连接
check_database() {
    print_title "数据库状态"
    
    local db_ok=true
    
    # 检查数据库是否存在
    if mysql -u "$DB_USER" -p"WJ20240824zyq" -e "USE $DB_NAME; SELECT 'Database accessible' as status;" >/dev/null 2>&1; then
        print_check "pass" "数据库连接正常"
        
        # 检查主要表是否存在
        local tables=(users notes files)
        for table in "${tables[@]}"; do
            if mysql -u "$DB_USER" -p"WJ20240824zyq" -e "USE $DB_NAME; DESCRIBE $table;" >/dev/null 2>&1; then
                print_check "pass" "数据表 $table 存在"
            else
                print_check "fail" "数据表 $table 不存在"
                db_ok=false
            fi
        done
    else
        print_check "fail" "数据库连接失败"
        db_ok=false
    fi
    
    return $db_ok
}

# 检查Web服务器配置
check_webserver() {
    print_title "Web服务器配置"
    
    local web_ok=true
    
    # 检查Nginx配置文件
    if [[ -f /etc/nginx/sites-available/personal-cloud-notes ]]; then
        print_check "pass" "Nginx站点配置存在"
    else
        print_check "fail" "Nginx站点配置不存在"
        web_ok=false
    fi
    
    # 检查站点是否启用
    if [[ -L /etc/nginx/sites-enabled/personal-cloud-notes ]]; then
        print_check "pass" "Nginx站点已启用"
    else
        print_check "fail" "Nginx站点未启用"
        web_ok=false
    fi
    
    # 检查Nginx配置语法
    if nginx -t >/dev/null 2>&1; then
        print_check "pass" "Nginx配置语法正确"
    else
        print_check "fail" "Nginx配置语法错误"
        web_ok=false
    fi
    
    return $web_ok
}

# 检查文件权限
check_permissions() {
    print_title "文件权限"
    
    local perm_ok=true
    
    # 检查部署目录所有者
    if [[ -d "$DEPLOY_PATH" ]]; then
        local owner=$(stat -c '%U' "$DEPLOY_PATH" 2>/dev/null || stat -f '%Su' "$DEPLOY_PATH" 2>/dev/null)
        if [[ "$owner" == "$DEPLOY_USER" ]]; then
            print_check "pass" "部署目录所有者正确 ($owner)"
        else
            print_check "fail" "部署目录所有者错误 (期望: $DEPLOY_USER, 实际: $owner)"
            perm_ok=false
        fi
    else
        print_check "fail" "部署目录不存在"
        perm_ok=false
    fi
    
    # 检查关键文件权限
    if [[ -f "$DEPLOY_PATH/.env" ]]; then
        local env_perm=$(stat -c '%a' "$DEPLOY_PATH/.env" 2>/dev/null || stat -f '%A' "$DEPLOY_PATH/.env" 2>/dev/null)
        if [[ "$env_perm" == "600" ]]; then
            print_check "pass" "环境配置文件权限正确 ($env_perm)"
        else
            print_check "warn" "环境配置文件权限可能不安全 ($env_perm)"
        fi
    fi
    
    return $perm_ok
}

# 检查网络连接
check_connectivity() {
    print_title "网络连接测试"
    
    local conn_ok=true
    
    # 测试HTTP连接
    if curl -s -o /dev/null -w "%{http_code}" "http://localhost" | grep -q "200\|301\|302"; then
        print_check "pass" "HTTP连接正常"
    else
        print_check "fail" "HTTP连接失败"
        conn_ok=false
    fi
    
    # 测试应用API
    if curl -s -o /dev/null -w "%{http_code}" "http://localhost/api/health" | grep -q "200"; then
        print_check "pass" "应用API响应正常"
    else
        print_check "warn" "应用API无响应（可能正在启动）"
    fi
    
    return $conn_ok
}

# 生成诊断报告
generate_report() {
    print_title "部署状态报告"
    
    local total_checks=6
    local passed_checks=0
    
    # 运行所有检查
    if check_services; then ((passed_checks++)); fi
    if check_ports; then ((passed_checks++)); fi
    if check_application; then ((passed_checks++)); fi
    if check_database; then ((passed_checks++)); fi
    if check_webserver; then ((passed_checks++)); fi
    if check_permissions; then ((passed_checks++)); fi
    
    # 网络连接测试（不计入总分）
    check_connectivity
    
    echo
    print_message "$CYAN" "总体状态:"
    print_message "$BLUE" "  检查项目: $total_checks"
    print_message "$GREEN" "  通过检查: $passed_checks"
    print_message "$RED" "  失败检查: $((total_checks - passed_checks))"
    
    local success_rate=$((passed_checks * 100 / total_checks))
    print_message "$BLUE" "  成功率: ${success_rate}%"
    
    echo
    if [[ $passed_checks -eq $total_checks ]]; then
        print_message "$GREEN" "🎉 部署状态良好！所有检查都通过了。"
        echo
        print_message "$CYAN" "访问信息:"
        print_message "$BLUE" "  网站地址: http://localhost"
        print_message "$BLUE" "  应用端口: $APP_PORT"
        return 0
    elif [[ $success_rate -ge 80 ]]; then
        print_message "$YELLOW" "⚠ 部署基本正常，但有一些问题需要注意。"
        return 1
    else
        print_message "$RED" "❌ 部署存在严重问题，需要修复。"
        echo
        print_message "$CYAN" "建议操作:"
        print_message "$BLUE" "  1. 检查服务状态: systemctl status nginx mysql"
        print_message "$BLUE" "  2. 查看应用日志: sudo -u $DEPLOY_USER pm2 logs"
        print_message "$BLUE" "  3. 重新运行部署脚本"
        return 2
    fi
}

# 显示帮助信息
show_help() {
    echo "部署状态检查脚本"
    echo
    echo "用法: $0 [部署路径]"
    echo
    echo "参数:"
    echo "  部署路径    应用部署的路径 (默认: /opt/personal-cloud-notes)"
    echo
    echo "选项:"
    echo "  --help, -h  显示帮助信息"
    echo
    echo "示例:"
    echo "  $0                           # 使用默认路径检查"
    echo "  $0 /custom/path             # 使用自定义路径检查"
    echo
}

# 主函数
main() {
    case "${1:-}" in
        --help|-h)
            show_help
            exit 0
            ;;
        *)
            print_title "个人云笔记部署状态检查"
            print_message "$BLUE" "检查路径: $DEPLOY_PATH"
            echo
            
            generate_report
            exit $?
            ;;
    esac
}

# 检查是否为root用户
if [[ $EUID -ne 0 ]]; then
    print_message "$YELLOW" "注意: 建议使用root权限运行以获得完整的检查结果"
    echo
fi

# 运行主函数
main "$@"